'use strict';
const BufRecver = require('./bufRecver.js');
const crc = require('./crc.js');

const FRAME_LEN_MAX = 256;
class Format extends BufRecver {
  constructor(lenMax) {
    super(lenMax || FRAME_LEN_MAX);
    this.msg = {
      leading: this.buf.slice(0, 3), //前导
      startTag: this.buf.slice(3, 5), //起始标识
      srcAddr: this.buf.slice(5, 13), //源地址
      dstAddr: this.buf.slice(13, 21), //目标地址
      ttl: this.buf.slice(21, 22), //生存时间
      type: this.buf.slice(22, 23), //协议类型
      version: this.buf.slice(23, 24), // 版本号
      control: this.buf.slice(24, 25), // 控制字段
      retransmit: this.buf.slice(25, 26), // 重传
      reserve1: this.buf.slice(26, 27), // 预留1
      errno: this.buf.slice(27, 28), // 错误码
      index: this.buf.slice(28, 30), // 命令序列号
      cmd: this.buf.slice(30, 32), // 命令标识
      len: this.buf.slice(32, 34), // 消息体长度
      body: this.buf.slice(34, this.bufLenMax - 7), // 消息体
      crc: this.buf.slice(this.bufLenMax - 7, this.bufLenMax - 5), // CRC校验
      endTag: this.buf.slice(this.bufLenMax - 5, this.bufLenMax - 3), //结束标识
      trailing: this.buf.slice(this.bufLenMax - 3, this.bufLenMax), //后继
    };
    Object.freeze(this.msg);
    this.msg.type[0] = 0;
    this.msg.version[0] = 3;
    this._index = [(Math.random() * 1000000) & 0xff, (Math.random() * 1000000) & 0xff];
  }

  setVar(field, data, dataLen) {
    if (field == 'body') {
      //设置指令序列号index
      if (this._index[1] == 0xff) {
        this._index[0]++;
        this._index[1] = 0x00;
      } else {
        this._index[1]++;
      }
      this.msg['index'][0] = this._index[0];
      this.msg['index'][1] = this._index[1];

      //设置消息体长度
      this.msg['len'][0] = dataLen >> 8;
      this.msg['len'][1] = dataLen;
      this.bufLen = 34 + dataLen;
    }
    for (let i = 0; i < dataLen; i++) {
      this.msg[field][i] = data[i];
    }
  }
  getData() {
    this.msg['leading'][0] = 0x55;
    this.msg['leading'][1] = 0x55;
    this.msg['leading'][2] = 0x55;
    this.msg['startTag'][0] = 0xd5;
    this.msg['startTag'][1] = 0x7e;

    let check = crc.get16(this.buf.slice(3, this.bufLen), this.bufLen - 3); //计算crc16

    this.buf[this.bufLen++] = check >> 8;
    this.buf[this.bufLen++] = check;
    this.buf[this.bufLen++] = 0x7d;
    this.buf[this.bufLen++] = 0x0a;
    this.buf[this.bufLen++] = 0x00;
    this.buf[this.bufLen++] = 0x00;
    this.buf[this.bufLen++] = 0x00;

    return Buffer.from(this.buf).slice(0, this.bufLen);
  }
  getMsg() {
    if (this.bufLen < 30) {
      return null;
    }
    let check = crc.get16(this.buf.slice(3, this.bufLen - 7), this.bufLen - 10); //计算crc16
    if (((this.buf[this.bufLen - 7] << 8) | this.buf[this.bufLen - 6]) == check) {
      let buf = Buffer.from(this.buf).slice(0, this.bufLen);
      let msg = {
        leading: buf.slice(0, 3), //前导
        startTag: buf.slice(3, 5), //起始标识
        srcAddr: buf.slice(5, 13), //源地址
        dstAddr: buf.slice(13, 21), //目标地址
        ttl: buf.slice(21, 22), //生存时间
        type: buf.slice(22, 23), //协议类型
        version: buf.slice(23, 24), // 版本号
        control: buf.slice(24, 25), // 控制字段
        retransmit: buf.slice(25, 26), // 重传
        reserve1: buf.slice(26, 27), // 预留1
        errno: buf.slice(27, 28), // 错误码
        index: buf.slice(28, 30), // 命令序列号
        cmd: buf.slice(30, 32), // 命令标识
        len: buf.slice(32, 34), // 消息体长度
        body: buf.slice(34, buf.length - 7), // 消息体
        crc: buf.slice(buf.length - 7, buf.length - 5), // CRC校验
        endTag: buf.slice(buf.length - 5, buf.length - 3), //结束标识
        trailing: buf.slice(buf.length - 3, buf.length), //后继
      };
      return msg;
    } else {
      return null;
    }
  }
}

module.exports = Format;
